var uploadHelp = module.exports;

var fs = require('fs');
var multiparty = require('multiparty');
var path = require('path');
var config = require('../config.js');
var mainPath = config.PICSMAINPATH;

// data {req: req, maxCount: 10, pathDir: xx}
// req传req
// maxCount  限制上传个数   5
// pathDir 自定义路径      xxx
// sizeLimit 最大文件限制  单位k
// checkFileNames   []
// necessaryParam   []
function doUploadFile(data) {
    return new Promise( (resolve, reject) => {
        // 最大文件2m
        var err = checkHasParam(data, ['req', 'maxCount', 'pathDir']).err;
        if(err) return reject({err: '服务器异常', errCode: 500});
        var form = new multiparty.Form({uploadDir: (mainPath + '/picTemp/')});
        form.parse(data.req, function(error, fields, files) {
            if(error) return reject({err: error, errCode: 400});
            var param = {};

            //整理参数
            for(var key in fields) {
                if(key[0]) {
                    param[key] = fields[key][0];
                }
            }

            //整理文件集合名
            param.fileNames = Object.keys(files);
            param.files = files;
            var fileCount = 0;
            var fileSizeArr = [];
            for(var key in files) {
                // todo 同个参数名多图  待扩展
                if(files[key].length > 1) {
                    return reject({err: '文件参数有误！', errCode: 400});
                }
                param[key] = files[key][0].path;
                fileCount += files[key].length;
                fileSizeArr.push(files[key][0].size);
            }

            //超过上传文件个数
            if(fileCount > param.maxCount) {
                return reject({err: '超过上传文件个数！', errCode: 400});
            }

            fileSizeArr.sort( (a, b) => {
                return a - b;
            }).reverse();

            const fileMaxSize  = param.sizeLimit ? param.sizeLimit * 1000 : 2000000;
            if(fileSizeArr[0] > fileMaxSize) {
                return reject({err: '文件过大,请重新选择文件', errCode: 400});
            }
            data.param = param;
            resolve(data);
        })
    })
}
function checkFileAndParam(data) {
    return new Promise((resolve, reject) => {
        if(data.checkFileNames && data.checkFileNames.length > 0 &&
            data.param.fileNames && data.param.fileNames.length > 0) {
            for(var i=0; i<data.param.fileNames.length; i++) {
                if(data.checkFileNames.indexOf(data.param.fileNames[i]) < 0) {
                    return reject({err:'文件参数有误！', errCode: 400});
                }
            }
        }

        if(data.necessaryParam && data.necessaryParam.length > 0) {
            var err = checkHasParam(data.param, data.necessaryParam).err;
            if(err) {
                return reject({err: err, errCode: 400});
            }
        }

        resolve(data);
    })
}
function builtPath(data) {
    return new Promise( (resolve, reject) => {
        if(!data.param.files) return reject({err: '文件参数有误！', errCode: 400});
        var uid = data.userInfo && data.userInfo.uid ? data.userInfo.uid : 0;
        var now = new Date();
        var filePath = '/' + data.pathDir;
        filePath += '/' + now.getFullYear();
        filePath += '/' + (now.getMonth()+1);
        filePath += '/' + now.getDate();
        if(uid) filePath += '/' + uid;
        mkdirs(mainPath + filePath, err => {
            if(err) return reject({err: err, errCode: 400});
            data.filePath = filePath + '/' + now.getHours() + now.getMinutes() + now.getSeconds() + now.getMilliseconds();
            resolve(data);
        })
    })
}
//递归创建目录 异步方法
function mkdirs(dirname, callback) {
    fs.exists(dirname, function (exists) {
        if (exists) {
            callback(null);
        } else {
            mkdirs(path.dirname(dirname), function () {
                fs.mkdir(dirname, callback);
            });
        }
    });
}
//changeDir(par, 0, userPath, function (err, par)
function renameFile(data, index, cb) {
    var keyArr = Object.keys(data.param.files);
    if(keyArr.length < 1) return cb(null, data);

    var fileObj = data.files[keyArr[index]][0];

    var uploadPath = fileObj.path;

    var suffix = fileObj.path.split('.')[1];

    var dstPath = mainPath + data.filePath + '.' + suffix;

    //重命名
    fs.rename(uploadPath, dstPath, err=> {
        if(err) return cb(err, data);
        data.param[fileObj.fieldName] = data.filePath + '.' + suffix;
        if(index < (keyArr.length-1)) {
            renameFile(data, index+1, cb)
        } else {
            cb(null, data);
        }
    })
}
uploadHelp.uploadFile = function(data) {
    return new Promise( (resolve, reject) => {
        doUploadFile(data).then( data => {
            return checkFileAndParam(data);
        }).then( data => {
            return builtPath(data);
        }).then( data => {
            renameFile(data, 0, (e, result) => {
                if(e) return reject({err:e, errCode: 400});
                resolve(result);
            })
        }).catch( err => {
            if(data.param && data.param.files) delFiles(data.param.files);
            reject(err);
        })
    })
}
//删除上传files
function delFiles(files) {
    for(var key in files) {
        files[key].forEach( fileObj => {
            var uploadPath = fileObj.path;
            fs.unlink(uploadPath, function() {});
        })
    }
}